package com.hbwxz;

import com.hbwxz.utils.CommonUtils;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.*;

/**
 * @author shenzw
 * @date 2023/12/10
 */
@Slf4j
public class Main {
    public static void main(String[] args) {
//        System.out.println(CommonUtils.readFile("file.txt")); // 演示读取文件
//        printContent("file.txt", "sensitive.txt"); // Future 演示替换文件中的敏感词
//        funAsyncDemo(); // 演示 funAsync
//        supplyAsyncDemo(); // 演示 supplyAsync
        supplyAsyncDemo2(); // 演示二：supplyAsync 指定线程池
    }

    /**
     * 替换 files.txt 文件中的敏感词汇，根据敏感词汇词库，多线程实现
     *
     * @param fileName 文件名
     */
    public static void printContent(String fileName, String sensitiveFileName) {

        // 创建线程池
        ExecutorService executor = Executors.newFixedThreadPool(5);

        // 线程一：读取源文件
        Future<String> sourceFileContext = executor.submit(() -> CommonUtils.readFile(fileName));

        // 线程二：读取敏感词库
        Future<String[]> sensitiveTask = executor.submit(() -> {
            String sensitiveContent = CommonUtils.readFile(sensitiveFileName);
            return sensitiveContent.split(",");
        });

        // 线程三（依赖线程一 和 线程二）：替换源文件的敏感词
        Future<String> resultTask = executor.submit(() -> {
            String sourceTaskGet = sourceFileContext.get(); // 会阻塞
            String[] sensitiveTaskGet = sensitiveTask.get(); // 会阻塞

            for (String s : sensitiveTaskGet) {
                if (sourceTaskGet.contains(s)) { // 存在敏感词汇
                    sourceTaskGet = sourceTaskGet.replace(s, "**");
                }
            }
            return sourceTaskGet;
        });

        // 输出内容
        try {
            CommonUtils.printThreadLog(resultTask.get()); // 会阻塞
        } catch (ExecutionException | InterruptedException e) {
            log.error("printContent is error.", e);
        } finally {
            executor.shutdown();
        }
    }

    /**
     * 演示 funAsync
     */
    public static void funAsyncDemo() {
        // runAsync 创建异步任务
        CommonUtils.printThreadLog("main start...");

        // 回顾普通线程
//        new Thread(() -> {
//            CommonUtils.printThreadLog("read file start...");
//            CommonUtils.sleepSecond(3);
//            CommonUtils.printThreadLog("read file end...");
//        }).start();

        // funAsync CompletableFuture 中的异步任务底层是通过开启线程的方式完成的
        CompletableFuture.runAsync(() -> {
            CommonUtils.printThreadLog("read file start...");
            CommonUtils.sleepSecond(3);
            CommonUtils.printThreadLog("read file end...");
        });

        CommonUtils.printThreadLog("here are not blocked，main continue...");
        CommonUtils.sleepSecond(4); // 此处休眠为的是等待 CompletableFuture 背后的线程池执行完成
        CommonUtils.printThreadLog("main end...");
    }

    /**
     * 演示 supplyAsync
     * 需求：开启异步任务读取 file.txt 文件中的数据，返回文件中的内容并在主线程打印输出
     */
    public static void supplyAsyncDemo() {
        CommonUtils.printThreadLog("main start...");
        CompletableFuture<String> fileContextFuture = CompletableFuture.supplyAsync(() -> {
            CommonUtils.printThreadLog("fileContextFuture read file start...");
            String s = CommonUtils.readFile("file.txt");
            CommonUtils.printThreadLog(s);
            return s;
        });

        CommonUtils.printThreadLog("here are not blocked，main continue.");
        // 阻塞并等待 fileContextFuture 完成
        try {
            CommonUtils.printThreadLog(fileContextFuture.get()); // 如果想要获取 newsFuture 结果，可以调用 completableFuture.get() 方法，get() 方法将阻塞，直到 fileContextFuture 完成；
        } catch (InterruptedException | ExecutionException e) {
            log.error("supplyAsyncDemo is error.", e);
        }
        CommonUtils.printThreadLog("main end...");

    }

    /**
     * 演示二： supplyAsync
     * 需求：指定线程池，开启异步任务读取 file.txt 文件中的数据，返回文件中的内容并在主线程打印输出
     */
    public static void supplyAsyncDemo2() {
        CommonUtils.printThreadLog("main start...");
//        AsyncConfiguration asyncConfiguration = new AsyncConfiguration();
//        Executor executor = asyncConfiguration.commonThreadPool();
        ExecutorService executor = Executors.newFixedThreadPool(4);
        CompletableFuture<String> fileContextFuture = CompletableFuture.supplyAsync(() -> {
            CommonUtils.printThreadLog("fileContextFuture read file start...");
            String s = CommonUtils.readFile("file.txt");
            CommonUtils.printThreadLog(s);
            return s;
        }, executor);

        CommonUtils.printThreadLog("here are not blocked，main continue.");
        // 阻塞并等待 fileContextFuture 完成
        try {
            CommonUtils.printThreadLog(fileContextFuture.get()); // 如果想要获取 newsFuture 结果，可以调用 completableFuture.get() 方法，get() 方法将阻塞，直到 fileContextFuture 完成；
        } catch (InterruptedException | ExecutionException e) {
            log.error("supplyAsyncDemo is error.", e);
        } finally {
            executor.shutdown();
        }
        CommonUtils.printThreadLog("main end...");

    }

}